package com.gopay.common.cps.dao.fund.impl;

import com.gopay.common.base.dao.impl.BaseDAOImpl;
import com.gopay.common.cps.dao.fund.BindCardBaseDAO;
import com.gopay.common.cps.dao.fund.BindCardDAO;
import com.gopay.common.cps.dao.fund.BindCardInfoDAO;
import com.gopay.common.cps.dao.fund.FundCpsMainDao;
import com.gopay.common.cps.dao.fund.FundCpsOrderDao;
import com.gopay.common.cps.dao.fund.FundDifferFileNotifyDAO;
import com.gopay.common.cps.dao.fund.FundFileDao;
import com.gopay.common.cps.dao.order.FundCpsGeneralMainOrderDao;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.domain.cps.CpsGenPayOrder;
import com.gopay.common.domain.fund.FundGopayBankcardInfoEntity;
import com.gopay.common.domain.fund.FundGopayCardEntity;
import com.gopay.common.domain.fund.FundGopayCpsGenOrder;
import com.gopay.common.domain.fund.FundGopayFileEntity;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author baiyunpeng
 * @2016年7月14日 下午3:36:05  www.gopay.com.cn Inc.All rights reserved.
 */
@Repository("bindCardBaseDAO")
public class BindCardBaseDAOImpl extends BaseDAOImpl<FundGopayBankcardInfoEntity, Serializable> implements BindCardBaseDAO {
    @Resource(name = "hibernateTemplate")
    private HibernateTemplate hibernateTemplate;
    @Resource(name = "bindCardDAO")
    private BindCardDAO bindCardDAO;
    @Resource(name = "bindCardInfoDAO")
    private BindCardInfoDAO bindCardInfoDAO;
    @Resource(name = "fundCpsOrderDao")
    private FundCpsOrderDao fundCpsOrderDao;
    @Resource(name = "fundFileDao")
    private FundFileDao fundFileDao;
    @Resource(name = "fundCpsMainDaoExt")
    private FundCpsMainDao fundCpsMainDao;
    @Resource(name = "fundCpsMainDao")
    private FundCpsGeneralMainOrderDao fundCpsGeneralMainOrderDao;
    @Resource(name = "fundDifferFileNotifyDAO")
    private FundDifferFileNotifyDAO fundDifferDao;

    @Override
    public Object get(Object obj) {
        Object object = null;
        List byExample = hibernateTemplate.findByExample(obj);
        if (byExample.size() != 0) {
            object = byExample.get(0);
        }
        return object;
    }

    @Override
    public Integer updateCard(Serializable agentSignNo, Serializable type) {
        if (!"".equals(agentSignNo) && agentSignNo != null) {
            StringBuffer sb = new StringBuffer("");
            sb.append("UPDATE FundGopayBankcardInfoEntity t set t.type=:type WHERE t.agentSignNo=:agentSignNo ");
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("type", type);
            map.put("agentSignNo", agentSignNo);
            return updateByHql(sb.toString(), map);
        }
        return null;
    }

    @Override
    public Integer updateCardInfo(Serializable agentSignNo, Serializable type, String keyId) {
        if (!"".equals(agentSignNo) && agentSignNo != null) {
            StringBuffer sb = new StringBuffer("");
            sb.append("UPDATE FundGopayBankcardInfoEntity t set t.type=:type WHERE t.agentSignNo=:agentSignNo AND t.keyId=:keyId");
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("type", type);
            map.put("agentSignNo", agentSignNo);
            map.put("keyId", keyId);
            return updateByHql(sb.toString(), map);
        }
        return null;
    }

    @Override
    public Object find(Serializable agentSignNo, Serializable merId, Serializable type) {
        if (!"".equals(agentSignNo) && agentSignNo != null) {
            String sql = " FROM  FundGopayBankcardInfoEntity WHERE type ='1' AND agentSignNo=:agentSignNo AND merchantId=:merchantId AND type=:type";
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("agentSignNo", agentSignNo);
            map.put("merchantId", merId);
            map.put("type", type);
            List<FundGopayBankcardInfoEntity> byHql = findByHql(sql, map);
            if (byHql.size() > 0) {
                FundGopayBankcardInfoEntity bankcardInfoEntity = byHql.get(0);
                return bankcardInfoEntity;
            }
        }
        return null;
    }

    @Override
    public Integer updateDtlForCardInfo(Serializable cardNo, Serializable bankCode, Serializable mobile, Serializable seq, Serializable memo, Date date) {
        if (!"".equals(cardNo) && cardNo != null && !"".equals(bankCode) && bankCode != null
                && !"".equals(mobile) && mobile != null) {
            if (!"".equals(memo) && memo != null) {
                StringBuffer sql = new StringBuffer("UPDATE FundGopayGenOrderTransDtl set cardNo=:cardNo , bankCode=:bankCode, mobile=:mobile, memo=:memo ,lastUpdTs=:lastUpdTs  WHERE transDtlSq=:seq");
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("cardNo", cardNo);
                map.put("bankCode", bankCode);
                map.put("mobile", mobile);
                map.put("memo", memo);
                map.put("seq", seq);
                map.put("lastUpdTs", date);
                return updateByHql(sql.toString(), map);
            } else {
                StringBuffer sql = new StringBuffer("UPDATE FundGopayGenOrderTransDtl set cardNo=:cardNo , bankCode=:bankCode, mobile=:mobile ,lastUpdTs=:lastUpdTs WHERE transDtlSq=:seq");
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("cardNo", cardNo);
                map.put("bankCode", bankCode);
                map.put("mobile", mobile);
                map.put("seq", seq);
                map.put("lastUpdTs", date);
                Integer i = updateByHql(sql.toString(), map);
                return i;
            }
        }
        return null;
    }

    @Override
    public FundGopayBankcardInfoEntity getEntity(String id, String agenSignNo) {
        if (!"".equals(id) && id != null && !"".equals(agenSignNo) && agenSignNo != null) {
            StringBuffer sql = new StringBuffer("from FundGopayBankcardInfoEntity where (agentSignNo=:agenSignNo and type=:id)");
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("agenSignNo", agenSignNo);
            map.put("id", id);
            List<FundGopayBankcardInfoEntity> byHql = findByHql(sql.toString(), map);
            if (byHql.size() > 0) {
                FundGopayBankcardInfoEntity bankcardInfoEntity = byHql.get(0);
                return bankcardInfoEntity;
            }
        }
        return null;
    }

    /**
     * 绑卡
     *
     * @param fundGopayBankcardInfoEntity
     * @param fundGopayCardEntity
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void saveOrder(FundGopayBankcardInfoEntity fundGopayBankcardInfoEntity, FundGopayCardEntity fundGopayCardEntity) {
        bindCardDAO.save(fundGopayCardEntity);
        bindCardInfoDAO.save(fundGopayBankcardInfoEntity);
    }

    /**
     * 解卡事务管理
     *
     * @param fundGopayCardEntity
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void unBindCard(FundGopayBankcardInfoEntity fundGopayBankcardInfoEntity, FundGopayCardEntity fundGopayCardEntity) {
        save(fundGopayBankcardInfoEntity);
        bindCardDAO.update(fundGopayCardEntity);
    }

    /**
     * 主从表成事务管理
     *
     * @param orderList
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveZeroOrder(final List<FundGopayCpsGenOrder> orderList, final List<CpsGenMainOrder> mainOrderList) {
        FundGopayCardEntity save = null;
        this.getHibernateTemplate().execute(new HibernateCallback<String>() {
            @Override
            public String doInHibernate(Session session) throws HibernateException, SQLException {
                // 获取连接
                Connection connection = session.connection();
                try {
                    // 关闭事务自动提交
                    connection.setAutoCommit(false);
                    fundCpsOrderDao.batchInsertMainOrders(connection, orderList);
                    //fundFileDao.saveFile(file);
                    fundCpsGeneralMainOrderDao.batchInsertMainOrders(connection, mainOrderList);
                    // 提交jdbc事务
                    connection.commit();
                } catch (SQLException e) {
                    // 手动回滚事物
                    connection.rollback();
                    throw e;
                }
                return null;
            }
        });
    }

    /**
     * 0文件生成事务管理
     *
     * @param orderList
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveThreeOrder(final List<FundGopayCpsGenOrder> orderList, final List<CpsGenMainOrder> mainOrderList, final List<CpsGenPayOrder> cpsGenPayOrderList, final Map<String, Object> map, final String key) {
        FundGopayCardEntity save = null;
        this.getHibernateTemplate().execute(new HibernateCallback<String>() {
            @Override
            public String doInHibernate(Session session) throws HibernateException, SQLException {
                // 获取连接
                Connection connection = session.connection();
                try {
                    // 关闭事务自动提交
                    connection.setAutoCommit(false);
                    fundCpsOrderDao.batchInsertMainOrders(connection, orderList);
                    //fundFileDao.saveFile(file);
                    fundCpsGeneralMainOrderDao.batchInsertMainOrders(connection, mainOrderList);
                    //不在事务里
                    fundFileDao.updateStatusFile(map, key);
                    // 提交jdbc事务
                    connection.commit();
                } catch (SQLException e) {
                    // 手动回滚事物
                    connection.rollback();
                    throw e;
                }
                return null;
            }
        });
    }

    /**
     * 上传3号文件事务
     *
     * @param fundOrderMaps
     * @param orderMaps
     * @param fileEntity
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public FundGopayFileEntity saveThreeFile(Map<String, Object> fundOrderMaps, Map<String, Object> orderMaps, FundGopayFileEntity fileEntity, FundGopayCpsGenOrder fundCpsMainOrder, CpsGenMainOrder cpsMainOrder) {
        if (fundOrderMaps != null && fundOrderMaps.size() > 0) {
            fundCpsOrderDao.updateFundMainOrder(fundOrderMaps);
        }
        if (orderMaps != null && orderMaps.size() > 0) {
            fundCpsOrderDao.updateMainOrder(orderMaps);
        }
        if (cpsMainOrder != null) {
            fundCpsMainDao.save(cpsMainOrder);
        }
        if (fundCpsMainOrder != null) {
            fundCpsOrderDao.save(fundCpsMainOrder);
        }
        return fundFileDao.saveFile(fileEntity);
    }

    /**
     * 对账差异文件成功更新状态
     *
     * @param maps
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void updateSuccessOrderCauseDiffer(Map<String, Map<String, Object>> maps) {
        Map<String, Object> fundGopayCpsGenOrder3 = maps.get("FundGopayCpsGenOrder3");
        Map<String, Object> cpsGenMainOrder3 = maps.get("CpsGenMainOrder3");
        Map<String, Object> cpsGenMainOrder27 = maps.get("CpsGenMainOrder27");
        Map<String, Object> fundGopayCpsGenOrder27 = maps.get("FundGopayCpsGenOrder27");
        fundCpsOrderDao.updateFundOrderCauseDiffer(fundGopayCpsGenOrder3, true);
        fundCpsOrderDao.updateMainOrderCauseDiffer(cpsGenMainOrder3, true);
        fundCpsOrderDao.updateMainOrderCauseDiffer(cpsGenMainOrder27, false);
        fundCpsOrderDao.updateFundOrderCauseDiffer(fundGopayCpsGenOrder27, false);

    }

    /**
     * 更新差异文件对账失败
     *
     * @param toatlMap
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void updateFailOrderCauseDiffer(final Map<String, Map<String, Object>> toatlMap) {

        Map<String, Object> fundGopayCpsGenOrder = toatlMap.get("FundGopayCpsGenOrder");
        Map<String, Object> fundGopayFileEntity = toatlMap.get("FundGopayFileEntity");
        Map<String, Object> cpsGenMainOrder = toatlMap.get("CpsGenMainOrder");
        fundCpsOrderDao.updateFundOrderCauseDifferByOrders(fundGopayCpsGenOrder);
        fundCpsOrderDao.updateMainOrderCauseDifferByOrders(fundGopayFileEntity);
        fundDifferDao.updateFundDifferFile(cpsGenMainOrder);
    }

    /**
     * 文件对账
     *
     * @param maps
     * @return
     */
    @Override
    public boolean checkerMoney(Map<String, Object> maps) {
        StringBuffer sql = new StringBuffer("");
        sql.append("");
        return false;
    }

    /**
     * 更新主从订单:在付款时候
     *
     * @param fundOrderMaps
     * @param orderMaps
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void updateMainAndFundOrder(Map<String, Object> fundOrderMaps, Map<String, Object> orderMaps) {
        fundCpsOrderDao.updateMainOrder(orderMaps);
        fundCpsOrderDao.updateFundMainOrder(fundOrderMaps);
    }

    @Override
    public void updateCardByBind(FundGopayCardEntity fundGopayCardEntity, FundGopayBankcardInfoEntity fundGopayBankcardInfoEntity) {
        save(fundGopayBankcardInfoEntity);
        bindCardDAO.update(fundGopayCardEntity);
    }



    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    @Override
    public void update02018And02012OrderState(String gopayId,String orderType){
        fundCpsOrderDao.updateFundCpsMainOrderTypeByGopayOrderId(gopayId,orderType);
        fundCpsOrderDao.updateFundCpsOrderStateByMermaker2(gopayId,orderType);
    }


    @Override
    public List<FundGopayCardEntity> getBindCard(Map<String, Object> param) {
        String sql = "select * from FUND_GOPAY_CARD t where t.AGENT_SIGN_NO = :agentSignNo and t.MERCHANT_ID = :merchantId and t.BANK_NO in (:cardNo) and t.TYPE = :type ";
        return bindCardDAO.findBySql(sql, param);
    }
}
